
package de.Hijack.Giuliani;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import java.util.ArrayList;
import org.redpin.android.core.Measurement;
import org.redpin.android.core.Vector;
import org.redpin.android.core.measure.WiFiReading;

/**
 *
 * @author Philipp
 */
public class DBAdapter {
    
    private static final String TAG = "DBAdapter";
    
    private static final String DATABASE_NAME = "locations";
    private static final String TABLE_MAIN = "location_table";
    private static final String KEY_ID = "id";
    private static final String KEY_LONGITUDE = "longi";
    private static final String KEY_LATITUDE = "lati";
    private static final String KEY_TEXT = "text";
    private static final String KEY_FLOOR = "floor";
    private static final String KEY_MEASUREMENT = "measure";
    private static final int DATABASE_VERSION = 1;
    
    private SQLiteDatabase db;
    
    SQLiteOpenHelper helper;
    Context context;
    
    public DBAdapter(Context context){
        this.context = context;
        helper = new SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {

            @Override
            public void onCreate(SQLiteDatabase db) {
                if (db == null) {
                    return;
                }
                db.execSQL("CREATE TABLE " + TABLE_MAIN + "(" + KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + KEY_LATITUDE + " INTEGER, " + KEY_LONGITUDE + " INTEGER, "+ KEY_TEXT + " TEXT, " + KEY_MEASUREMENT + " TEXT," + KEY_FLOOR + " INTEGER);");
            }

            @Override
            public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
                // NOT NEEDED YET
            }
        };
    }
    
    public ArrayList<WayPoint> getPoints(){
        ArrayList<WayPoint> list = new ArrayList<WayPoint>();
        Cursor cursor = db.query(TABLE_MAIN, null, null, null, null, null, null);
        if(cursor.moveToFirst()){
            do{
                WayPoint p = new WayPoint(cursor.getInt(1),cursor.getInt(2));
                p.setDescription(cursor.getString(3));
                p.measurement = getMeasurement(cursor.getString(4));
                p.id = cursor.getInt(0);
                p.floor = cursor.getInt(5);
                list.add(p);
                Log.d(TAG, "got a point: "+cursor.getInt(1)+", "+cursor.getInt(2));
            }while(cursor.moveToNext());
        }
        cursor.close();
        return list;
    }
    
    public void addPoint(WayPoint p){
        Log.d(TAG, "saving point: "+p.getLatitudeE6()+", "+p.getLongitudeE6());
        if(p.measurement==null){
            db.execSQL("INSERT INTO " + TABLE_MAIN + " (" + KEY_LATITUDE + ", " + KEY_LONGITUDE + ", " + KEY_TEXT+", "+KEY_FLOOR+") VALUES (\"" + p.getLatitudeE6() + "\", \"" + p.getLongitudeE6() + "\", \"" + p.getDescription()+ "\", \"" + (-1) + "\");");
        }else{
            Log.d(TAG, "saved Measurement: "+p.measurement.toString());
            db.execSQL("INSERT INTO " + TABLE_MAIN + " (" + KEY_LATITUDE + ", " + KEY_LONGITUDE + ", " + KEY_TEXT+ ", "+ KEY_MEASUREMENT +", "+KEY_FLOOR+") VALUES (\"" + p.getLatitudeE6() + "\", \"" + p.getLongitudeE6() + "\", \"" + p.getDescription() + "\", \"" + getString(p.measurement) + "\", \"" + p.floor +  "\");");
        }
    }
    
    /**
     * updates a point using its id
     * @param p the point to update
     */
    public void apply(WayPoint p){
        db.execSQL("UPDATE " + TABLE_MAIN + " SET " + KEY_TEXT + " = \"" + p.getDescription() + "\" WHERE " + KEY_ID + " = " + p.id);
    }
    
    /**
     * deletes a point using its id
     * @param p the point to delete
     */
    public void delete(WayPoint p){
        db.execSQL("DELETE FROM " + TABLE_MAIN + " WHERE " + KEY_ID + " = \"" + p.id + "\"");
    }
    
    public void open() {
        try {
            db = helper.getWritableDatabase();
        } catch (Exception e) {
            Log.e(TAG, "Error opening databse");
        }
    }
    
    public void close() {
        if (db == null) {
            return;
        }
        db.close();
    }

    /**
     * gets a measurement from a string like its saved in the database
     * @param string
     * @return 
     */
    private Measurement getMeasurement(String string) {
        Measurement m = new Measurement();
        Vector<WiFiReading> wr = new Vector<WiFiReading>();
        String[] str;
        try{
            str = string.split("#_1");
        }catch(NullPointerException e){
            return null;
        }
        for(String s : str){
            try{
                WiFiReading w = new WiFiReading();
                w.setBssid(s.split("#_2")[0]);
                w.setSsid(s.split("#_2")[1].split("#_3")[0]);
                w.setRssi(Integer.parseInt(s.split("#_2")[1].split("#_3")[1].split("#_4")[0]));
                w.setInfrastructure(s.split("#_2")[1].split("#_3")[1].split("#_4")[1].split("#_5")[0].equals("1"));
                w.setWepEnabled(s.split("#_2")[1].split("#_3")[1].split("#_4")[1].split("#_5")[1].equals("1"));
                wr.add(w);
            }catch(Exception e){
                Log.d(TAG,"Error parsing Measurement WiFiReading");
            }
        }
        if(wr.size()== 0){
            return null;
        }
        m.setWiFiReadings(wr);
        Log.d(TAG, "got Measurement: "+m.toString());
        return m;
    }
    
    /**
     * converst a measurement to a string so you can easier save it in the db
     * @param m
     * @return 
     */
    private String getString(Measurement m){
        String str = "";
        for(WiFiReading w : m.getWiFiReadings()){
            str += "#_1";
            str += w.getBssid()+"#_2";
            str += w.getSsid()+"#_3";
            str += w.getRssi()+"#_4";
            str += w.isInfrastructure()?"1":"0"+"#_5";
            str += w.isWepEnabled()?"1":"0";
        }
        return str;
    }

    
}
